home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
dnsconf
/
origin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-30
|
5KB
|
247 lines
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "dnsconf.h"
#include "internal.h"
/*
fgets with support for continuation line
*/
static char *record_fgets(
char *buf,
int size,
FILE *fin)
{
char *ret = NULL;
bool cont = false;
while (fgets(buf,size,fin)!=NULL){
if (ret == NULL) ret = buf;
char *ptp = strchr (buf,';');
if (ptp != NULL) *ptp = '\0';
char *ptc = strchr (buf,'(');
char *pte = strchr (buf,')');
if (ptc != NULL){
// Openning parenthese
*ptc = ' ';
cont = true;
}else if (pte != NULL){
// Closing parenthese
*pte = ' ';
cont = false;
}
if (!cont) break;
int len = strlen(buf);
buf += len;
size -= len;
}
return ret;
}
PUBLIC ORIGIN::ORIGIN (const char *_origin)
{
origin.setfrom (_origin);
}
PUBLIC void ORIGIN::print(bool save_ori, TBFILE &tbf) const
{
// We don't put $ORIGIN at the beginning of the file
// because it is implied
if (save_ori) fprintf (tbf.cur,"$ORIGIN %s\n",origin.get());
tbrec.save(tbf);
}
PUBLIC void ORIGIN::edit()
{
}
/*
Locate all IP number in use in that area (sub origin) of a domain.
Return the number added to adrs
*/
PUBLIC int ORIGIN::getalladr(IP_ADDRS &adrs)
{
int ret = 0;
int n = tbrec.getnb();
for (int i=0; i<n; i++){
RECORD *rec = tbrec.getitem(i);
if (rec->is(RTYPE_A)){
RECORD_IN_A *in = (RECORD_IN_A*)rec;
adrs.add (new IP_ADDR(in->addr));
ret++;
}
}
return ret;
}
/*
Return != if any component of the ORIGIN was modified
*/
PUBLIC int ORIGIN::was_modified()
{
int ret = ARRAY_OBJ::was_modified();
if (!ret){
ret = tbrec.was_modified();
}
return ret;
}
PRIVATE int ORIGINS::parsespecial(
const char *key,
const char *pt,
TBFILE &tbf,
ORIGIN *&ori)
{
int ret = 0;
pt = str_skip(pt);
char arg[200];
pt = str_copyword (arg,pt);
if (stricmp(key,"$ORIGIN")==0){
ori = new ORIGIN(arg);
add (ori);
}else if (stricmp(key,"$INCLUDE")==0){
ori->tbrec.add (new RECORD_INCLUDE(arg));
ret = tbf.fopen (arg,"r") != NULL ? 0 : -1;
}else{
ret = -1;
}
return ret;
}
/*
Complete the parsing of the line, pt point to the TTL maybe
Return NULL if any error or a new RECORD.
*/
PRIVATE int ORIGINS::parseend (
char *pt,
RECORD_PARSE &p,
ORIGIN *ori)
{
int ret = -1;
pt = str_skip(pt);
if (isdigit(*pt)){
p.ttl = atoi(pt);
p.nottl = false;
while (isdigit(*pt)) pt++;
pt = str_skip(pt);
}
char keyword[200];
pt = str_copyword (keyword,pt);
if (stricmp(keyword,"IN")==0){
pt = str_skip(pt);
pt = str_copyword (keyword,pt);
pt = str_skip(pt);
pt = str_copyword (p.f2,pt);
pt = str_skip(pt);
pt = str_copyword (p.f3,pt);
pt = str_skip(pt);
pt = str_copyword (p.f4,pt);
pt = str_skip(pt);
pt = str_copyword (p.f5,pt);
pt = str_skip(pt);
pt = str_copyword (p.f6,pt);
pt = str_skip(pt);
pt = str_copyword (p.f7,pt);
pt = str_skip(pt);
pt = str_copyword (p.f8,pt);
RECORD *o = NULL;
if (stricmp(keyword,"A")==0){
o = new RECORD_IN_A(p);
}else if (stricmp(keyword,"MX")==0){
o = new RECORD_IN_MX(p);
}else if (stricmp(keyword,"NS")==0){
o = new RECORD_IN_NS(p);
}else if (stricmp(keyword,"PTR")==0){
o = new RECORD_IN_PTR(p);
}else if (stricmp(keyword,"CNAME")==0){
o = new RECORD_IN_CNAME(p);
}else if (stricmp(keyword,"SOA")==0){
o = new RECORD_IN_SOA(p);
}
if (o != NULL){
ori->tbrec.add(o);
ret = 0;
}else{
ret = -1;
}
}
return ret;
}
PUBLIC ORIGIN *ORIGINS::getitem(int no) const
{
return (ORIGIN*)ARRAY::getitem(no);
}
/*
Read a file with a bunch of IN records and manage those.
*/
PUBLIC int ORIGINS::read (
const char *named_dir,
const char *fname,
const char *first_origin)
{
/*
Reading a record file is complicate. It may contain
several $origin statement and several $include statement.
We maintain the records as a set of several origin related
list. In those list, we maintain special record indicating
the beginning and end of an include file scope.
*/
ORIGIN *ori = new ORIGIN(first_origin);
add (ori);
int ret = -1;
TBFILE tbf(named_dir);
tbf.fopen(fname,"r");
while (tbf.cur != NULL){
char buf[10000];
ret = 0;
while (record_fgets(buf,sizeof(buf)-1,tbf.cur)!=NULL){
strip_end (buf);
RECORD_PARSE parse;
if (buf[0] > ' ' && buf[0] != ';'){
char *pt = str_copyword (parse.f1,buf);
if (parse.f1[0] == '$'){
ret = parsespecial (parse.f1,pt
,tbf,ori);
}else{
ret = parseend (pt,parse,ori);
}
}else if (buf[0] != '\0'){
char *pt = str_skip (buf);
if (*pt == ';'){
ori->tbrec.add (new RECORD_COMMENT(buf));
}else{
ret = parseend (pt,parse,ori);
}
}
}
tbf.fclose ();
if (tbf.cur != NULL) ori->tbrec.add (new RECORD_END_INCLUDE);
}
return ret;
}
/*
Save in a file a bunch of IN records.
*/
PUBLIC int ORIGINS::save (
const char *named_dir,
const char *fname) const
{
int ret = -1;
TBFILE tbf(named_dir);
if (tbf.fopen(fname,"w") != NULL){
ret = 0;
for (int i=0; i<getnb(); i++){
getitem(i)->print (i != 0 ,tbf);
}
}
return ret;
}